﻿#pragma execution_character_set("utf-8")
#include "httpclient.h"

HttpClient::HttpClient(QObject *parent) :
    QObject(parent),
    manager(new QNetworkAccessManager(this))
{
    connect(manager, &QNetworkAccessManager::finished, this, &HttpClient::onReplyFinished);
}
HttpClient::HttpClient(const QString &baseUrl,QObject *parent) :
    QObject(parent),
    manager(new QNetworkAccessManager(this)),
    baseUrl(baseUrl)
{
    connect(manager, &QNetworkAccessManager::finished, this, &HttpClient::onReplyFinished);
}
HttpClient::HttpClient(const QString &baseUrl,const QString &token,QObject *parent) :
    QObject(parent),
    manager(new QNetworkAccessManager(this)),
    baseUrl(baseUrl),
    token(token.toUtf8())
{
    connect(manager, &QNetworkAccessManager::finished, this, &HttpClient::onReplyFinished);
}

HttpClient::~HttpClient()
{
    manager->deleteLater();
}

QNetworkReply* HttpClient::post(const QNetworkRequest &request,const QByteArray &data){//发送请求，并保存请求
    return manager->post(request, data);//发送post请求
}
QNetworkReply* HttpClient::postJson(const QUrl &url,const QByteArray &data){//设置请求头
    QNetworkRequest request(url);
    request.setRawHeader("token",token);
    request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
    return post(request,data);
}

QNetworkReply* HttpClient::postFile(const QUrl &url,const QByteArray &data){//设置请求头
    QNetworkRequest request(url);
    request.setRawHeader("token",token);
    request.setHeader(QNetworkRequest::ContentTypeHeader, "application/octet-stream");
    return post(request,data);
}

QNetworkReply* HttpClient::post(const QString &url,const QByteArray &data){
    if(url.contains("download"))
        return postFile(handleUrl(url),data);
    else
        return postJson(handleUrl(url),data);
}

QNetworkReply* HttpClient::post(const QUrl &url,QHttpMultiPart *multiPart){//用于处理文件上传
    QNetworkRequest request(url);
    request.setRawHeader("token",token);
    return manager->post(request, multiPart);//发送post请求
}

QNetworkReply* HttpClient::get(const QString &url){
    if(url.contains("get_head_img"))
        return getFile(handleUrl(url));
    else
        return getJson(handleUrl(url));
}
QNetworkReply* HttpClient::getJson(const QUrl &url){
    QNetworkRequest request(url);
    request.setRawHeader("token",token);
    request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
    return get(request);
}
QNetworkReply* HttpClient::getFile(const QUrl &url){
    QNetworkRequest request(url);
    request.setRawHeader("token",token);
    request.setHeader(QNetworkRequest::ContentTypeHeader, "application/octet-stream");
    return get(request);
}
QNetworkReply* HttpClient::get(const QNetworkRequest &request){
    return manager->get(request);//发送get请求
}

QNetworkReply* HttpClient::sendTextMsg(const QByteArray &data){
    if(!baseUrl.isEmpty()){
        return post("/App/sendMessage",data);
    }
    else
    {
        qDebug()<<"############## CONNECTION ERROR ##############";
        qDebug()<<"baseUrl is Empty";
        qDebug()<<"##############################################";
        return nullptr;
    }
}

QNetworkReply* HttpClient::upLoadFile(const QString &url,const QString &path,const QString &uuid)
{
    QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
    // 添加文件部分
    QHttpPart filePart;
    filePart.setHeader(QNetworkRequest::ContentDispositionHeader,QVariant("form-data; name=\"file\"; filename=\"" + uuid+"."+QFileInfo(path).suffix() + "\""));
    filePart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/octet-stream"));

    QFile *file = new QFile(path);
    if (file->open(QIODevice::ReadOnly)) {// 确保在multiPart被删除时文件也被删除
        filePart.setBodyDevice(file);
        file->setParent(multiPart);
    } else {// 处理文件打开失败的情况
        qDebug()<<"upload file : "<<path<<" is ERROR";
    }

    multiPart->append(filePart);
    return post(handleUrl(url),multiPart);
}

QNetworkReply* HttpClient::downLoadFile(const QString &url, const QByteArray &data)
{
    return post(url,data);
}

QString HttpClient::handleUrl(const QString &url){
    QString path(url);
    if (!baseUrl.isEmpty()&&!path.startsWith('/')) {
        path.prepend("/");
    }
    return baseUrl+path;
}

void HttpClient::setBaseUrl(const QString &url){
    this->baseUrl=url;
}

void HttpClient::setToken(const QString &token){
    this->token=token.toUtf8();
}

void HttpClient::onReplyFinished(QNetworkReply *reply)
{
//    reply->downloadProgress();
    QUrl url = reply->url();
    if (!url.isEmpty()) {
        if (reply->error() == QNetworkReply::NoError) {//发送请求成功
            QByteArray responseData = reply->readAll();
            printDetail(url,responseData);
            emit finished(url, responseData); // 发射带有URL的信号
        } else {//发送请求失败
            printError(url,reply->errorString());
            emit errorOccurred(url, reply->error()); // 发射带有URL和错误信息的信号
        }
    }
    else{
        qDebug()<<"############## CONNECTION ERROR ##############";
        qDebug()<<"ERROR INFO : url is NULL";
        qDebug()<<"##############################################";
    }
    reply->deleteLater(); // 不再需要reply对象时删除它
}
void HttpClient::printDetail(const QUrl &url,const QByteArray &responseData){
    qDebug()<<"-------------- CONNECTION DATA --------------";
    qDebug()<<"URL :"<<url;
    qDebug()<<"FROM : SERVER";
    if(responseData.size()>5000)
        qDebug()<<"SIZE : "<<responseData.size()<<" byte(字节)";
    else
        qDebug()<<"CONTENT : "<<responseData;
    qDebug()<<"---------------------------------------------";
}
void HttpClient::printError(const QUrl &url,const QString &errorString){
    qDebug()<<"############## CONNECTION ERROR ##############";
    qDebug()<<"connect to "<<url.toString()<<" is fail";
    qDebug()<<"ERROR INFO : "<<errorString;
    qDebug()<<"##############################################";
}
